﻿#pragma once
#include <functional>
#include <utility>

#if __cplusplus >= 202002L
namespace as
{
	namespace tools
	{
		struct scope_guard {
			std::function<void()>f;

			//方法1
			/*template<typename Func, typename...Args> requires std::invocable<Func, std::unwrap_reference_t<Args>...>
			scope_guard(Func &&func, Args&&...args) :f{ [func = std::forward<Func>(func), ...args = std::forward<Args>(args)]() mutable {
					std::invoke(std::forward<std::decay_t<Func>>(func), std::unwrap_reference_t<Args>(std::forward<Args>(args))...);
				} } {}*/

				//方法2
			template<typename Func, typename... Args>
			scope_guard(Func &&func, Args &&...args)
				:f(std::bind_front(std::forward<Func>(func), std::forward<Args>(args)...))
			{

			}

			~scope_guard() { f(); }
			scope_guard(const scope_guard &) = delete;
			scope_guard &operator=(const scope_guard &) = delete;
		};
	}
}
#endif